﻿using Dos.ORM;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Dos.ORMHelper
{
    public class DbHelper
    {
        public static DbSession _DbContext = null;
        //static string connectionString = ConfigurationManager.ConnectionStrings["APIConnectionString"].ConnectionString;
        static string connectionString = "Data Source=(Local);Initial Catalog={0};Integrated Security=True";
        /// <summary>
        /// 初始化DBSession
        /// </summary>
        public static void InitDbSession(string dbName)
        {
            if (_DbContext == null)
            {
                _DbContext = new DbSession(DatabaseType.SqlServer, string.Format(connectionString, dbName));
            }
        }
    }
    /// <summary>
    /// 基础父类（使用只需继承该类就行)
    /// </summary>
    /// <typeparam name="M"></typeparam>
    public class BaseService<M> where M : Entity, new()
    {
        /// <summary>
        /// 查询全部
        /// </summary>
        public static DbSession DbContext
        {
            get
            {

                return DbHelper._DbContext;
            }
        }
        public static FromSection<M> GetFromSection()
        {
            return DbContext.From<M>();
        }
        public static DbTrans BeginTransaction(IsolationLevel isolation = IsolationLevel.Serializable)
        {
            return DbContext.BeginTransaction(isolation);
        }

        #region CRUD Functions

        #region Create


        /// <summary>
        /// 实体插入
        /// </summary>
        /// <param name="model"></param>
        /// <param name="trans"></param>
        /// <returns></returns>
        public static int Insert(M model, DbTrans trans = null)
        {
            bool commitIsNeeded = trans != null;
            try
            {
                if (!commitIsNeeded)
                    trans = DbContext.BeginTransaction(IsolationLevel.Serializable);

                var result = DbContext.Insert<M>(trans, model);

                if (!commitIsNeeded)
                    trans.Commit();
                return result;

            }
            catch (Exception ex)
            {
                //Log4Helper.Write("插入发生异常", ex);
                trans.Rollback();
                return -1;
            }


        }

        /// <summary>
        /// 多条插入
        /// </summary>
        /// <param name="models"></param>
        /// <param name="trans"></param>
        /// <returns></returns>
        public static bool Insert(List<M> models, DbTrans trans = null)
        {
            bool commitIsNeeded = trans != null;
            try
            {
                if (!commitIsNeeded)
                    trans = DbContext.BeginTransaction(IsolationLevel.Serializable);

                var result = DbContext.Insert<M>(trans, models);

                if (!commitIsNeeded)
                    trans.Commit();
                if (result > 0)
                    return true;
                else
                    return false;
            }
            catch (Exception ex)
            {
                //LogHelper.Write("批量插入发生异常", ex);
                if (!commitIsNeeded)
                    trans.Rollback();
                return false;
            }
        }

        /// <summary>
        /// IEnumerable<M>插入
        /// </summary>
        /// <param name="models"></param>
        /// <returns></returns>
        public static int Insert(IEnumerable<M> models)
        {
            return DbContext.Insert(models);
        }

        #endregion Insert

        #region Read

        /// <summary>
        /// 获取全部
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<M> GetAll()
        {
            return DbContext.From<M>().ToEnumerable();
        }

        /// <summary>
        /// 获取所有返回list
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<T> GetAll<T>()
        {
            return DbContext.From<M>().ToList<T>();
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static IEnumerable<M> Query(Expression<Func<M, bool>> predicate)
        {
            return DbContext.From<M>().Where(predicate).ToEnumerable();
        }
        /// <summary>
        /// 获取总数
        /// </summary>
        /// <returns></returns>
        public static int Count()
        {
            return DbContext.From<M>().Count();
        }
        /// <summary>
        /// 基础查询
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <returns></returns>
        public static FromSection<M> BaseQuery()
        {
            return DbContext.From<M>();
        }
        /// <summary>
        /// 查询语句直接查询DataSet
        /// </summary>
        /// <param name="sql">SQL语句</param>
        public static DataSet QuerySql(string sql)
        {
            return DbContext.FromSql(sql).ToDataSet();
        }
        //public void QueryBySql(string sql)
        //{
        //    SqlSection sqlSection = new SqlSection(DbContext, sql);
        //    sqlSection.
        //}
        /// <summary>
        /// 查询语句直接查询List<T>
        /// </summary>
        /// <typeparam name="T">要转换的实体对象</typeparam>
        /// <param name="sql">SQL语句</param>
        public static List<T> QuerySql<T>(string sql)
        {
            return DbContext.FromSql(sql).ToList<T>();
        }

        /// <summary>
        /// 判断是否存在
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static bool Any(Expression<Func<M, bool>> predicate)
        {
            return DbContext.Exists<M>(predicate);
        }

        /// <summary>
        /// 最新的
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        public static M GetLast(Field field)
        {
            return DbContext.From<M>().OrderByDescending(field).Top(1).ToFirst();
        }

        #endregion Read

        #region Update


        /// <summary>
        /// 事务更新
        /// </summary>
        /// <param name="isolationLevel"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public static bool UpdateWithTransaction(IsolationLevel isolationLevel, M model)
        {
            var trans = DbContext.BeginTransaction(isolationLevel);
            try
            {
                DbContext.Update(trans, model);
                trans.Commit();
                return true;
            }
            catch (Exception)
            {
                trans.Rollback();
                return false;
            }
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="models"></param>
        /// <returns></returns>
        public static int Update(IEnumerable<M> models)
        {
            var enumerable = models as M[] ?? models.ToArray();
            DbContext.Update(enumerable.ToArray());
            return 1;
        }

        /// <summary>
        /// 单挑更新
        /// </summary>
        /// <param name="model"></param>
        /// <param name="trans"></param>
        /// <returns></returns>
        public static int Update(M model, DbTrans trans = null)
        {
            bool commitIsNeeded = trans != null;

            if (!commitIsNeeded)
                trans = DbContext.BeginTransaction(IsolationLevel.Serializable);

            var result = DbContext.Update<M>(trans, model);

            if (!commitIsNeeded)
                trans.Commit();

            return result;
        }

        /// <summary>
        /// 事务更新列表
        /// </summary>
        /// <param name="isolationLevel"></param>
        /// <param name="models"></param>
        /// <returns></returns>
        public static bool UpdateWithTransaction(IsolationLevel isolationLevel, IEnumerable<M> models)
        {
            var trans = DbContext.BeginTransaction(isolationLevel);
            try
            {
                DbContext.Update(trans, models.ToArray());
                trans.Commit();
                return true;
            }
            catch (Exception)
            {
                trans.Rollback();
                return false;
            }
        }

        /// <summary>
        /// 单个更新（带事务）
        /// </summary>
        /// <param name="models"></param>
        /// <param name="trans"></param>
        /// <returns></returns>
        public static bool Update(List<M> models, DbTrans trans = null)
        {
            bool commitIsNeeded = trans != null;

            if (!commitIsNeeded)
                trans = DbContext.BeginTransaction(IsolationLevel.Serializable);

            var result = DbContext.Update<M>(trans, models);

            if (!commitIsNeeded)
                trans.Commit();

            return result == models.Count;
        }

        #endregion Update

        #region Delete

        /// <summary>
        /// 删除（带事务）
        /// </summary>
        /// <param name="model"></param>
        /// <param name="trans"></param>
        /// <returns></returns>
        public static int Delete(M model, DbTrans trans = null)
        {
            bool commitIsNeeded = trans != null;

            if (!commitIsNeeded)
                trans = DbContext.BeginTransaction(IsolationLevel.Serializable);

            var result = DbContext.Delete<M>(trans, model);

            if (!commitIsNeeded)
                trans.Commit();

            return result;
        }

        /// <summary>
        /// 删除多条
        /// </summary>
        /// <param name="models"></param>
        /// <returns></returns>
        public static int Delete(IEnumerable<M> models)
        {
            return DbContext.Delete<M>(models);
        }

        /// <summary>
        /// 带事务删除多条
        /// </summary>
        /// <param name="models"></param>
        /// <param name="trans"></param>
        /// <returns></returns>
        public static int Delete(IEnumerable<M> models, DbTrans trans = null)
        {
            bool commitIsNeeded = trans != null;

            if (!commitIsNeeded)
                trans = DbContext.BeginTransaction(IsolationLevel.Serializable);

            var result = DbContext.Delete<M>(trans, models);

            if (!commitIsNeeded)
                trans.Commit();
            return result;
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="trans"></param>
        /// <returns></returns>
        public static int Delete(Expression<Func<M, bool>> predicate, DbTrans trans)
        {
            return DbContext.Delete<M>(trans, predicate);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static int Delete(Expression<Func<M, bool>> predicate)
        {
            return DbContext.Delete<M>(predicate);
        }

        public static int DeleteAll()
        {
            return DbContext.DeleteAll<M>();
        }

        #endregion Delete

        #endregion CRUD Functions
        /// <summary>
        /// 获取事务
        /// </summary>
        /// <returns></returns>
        public static DbTrans GetTrans()
        {
            return DbContext.BeginTransaction();
        }

    }
}
